package com.class04.lambda;

import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;

/**
 * @ClassDescription:
 * 1.lambda表达式的使用举例
 * (o1,o2)->Integer.compare(o1,o2);
 * 2.lambda表达式的格式举例
 * lambda形参列表 ->  lambda体
 * 3. Lambda表达式的格式
 *
 * -> : lambda操作符或箭头操作符
 * -> 的左边: lambda形参列表，对应着要重写的接口中的抽象方法的形参列表。
 * -> 的右边: lambda体，对应着接口的实现类要重写的方法的方法体。
 *
 * 4. Lambda表达式的本质：
 * > 一方面，lambda表达式作为接口的实现类的对象。  ---> "万事万物皆对象"
 * > 另一方面，lambda表达式是一个匿名函数。
 *
 *
 * 5. 函数式接口：
 * 5.1 什么是函数式接口？为什么需要函数式接口？
 *
 * > 如果接口中只声明有一个抽象方法，则此接口就称为函数式接口。
 *
 * > 因为只有给函数式接口提供实现类的对象时，我们才可以使用lambda表达式。
 *
 *
 * 5.2 api中函数式接口所在的包
 *
 * jdk8中声明的函数式接口都在java.util.function包下。
 *
 *
 * 5.3 4个基本的函数式接口
 *           接口            对应的抽象方法
 * 消费型接口：Consumer<T>     void accept(T t)
 * 供给型接口：Supplier<T>     T get()
 * 函数型接口：Function<T,R>   R apply(T t)
 * 判断型接口：Predicate<T>    boolean test(T t)
 *
 * 6. Lambda表达式的语法规则总结
 *
 * -> 的左边：lambda形参列表，参数的类型都可以省略。如果形参只有一个，则一对()也可以省略。
 *
 * -> 的右边：lambda体，对应着重写的方法的方法体。如果方法体中只有一行执行语句，则一对{}可以省略。
 *                                        如果有return关键字，则必须一并省略。
 * @JdkVersion: 17
 * @Author: yxy
 * @Created: 2023/11/28 15:31
 */
public class LambdaTest1 {
    @Test//语法格式1：无参无返回值
    public void test1() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        };
        runnable.run();
        System.out.println("==============================");
        Runnable r1 = () -> {
            System.out.println("hello");
        };
        r1.run();

    }

    @Test//语法格式2：需要一个参数，但是没有返回值
    public void test2() {
        Consumer<String> con = new Consumer<String>() {
            @Override
            public void accept(String o) {
                System.out.println("o = " + o);
            }
        };
        con.accept("大数据");
        System.out.println("==========================");
        Consumer<String> con1 = (String o) -> {
            System.out.println("o = " + o);
        };
        con1.accept("大数据");
    }

    @Test//语法格式3：数据类型可以省略，因为可由编译器推断得出，称为“类型推断”
    public void test3() {
        Consumer<String> con1 = (String o) -> {
            System.out.println("o = " + o);
        };
        con1.accept("大数据1");
        System.out.println("==========================");
        Consumer<String> con2 = (o) -> {
            System.out.println("o = " + o);
        };
        con1.accept("大数据2");

    }


    @Test//语法格式4：lambda 若只需要一个参数时，参数的小括号可以省略
    public void test4() {

        Consumer<String> con2 = (o) -> {
            System.out.println("o = " + o);
        };
        con2.accept("大数据2");

        System.out.println("==========================");
        Consumer<String> con3 = o -> {
            System.out.println("o = " + o);
        };
        con2.accept("大数据2");


    }

    @Test//语法格式5：lambda 需要两个或以上的参数，多条执行语句，并且可以有返回值
    public void test5() {
        Comparator<Integer> con = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {

                System.out.println("o1 = " + o1);
                System.out.println("o2 = " + o2);
                return o1.compareTo(o2);
            }
        };
        int compare = con.compare(12, 32);
        System.out.println("=======================================");
        Comparator<Integer> con1 = (o1, o2) -> {

            System.out.println("o1 = " + o1);
            System.out.println("o2 = " + o2);
            return o1.compareTo(o2);
        };
        int compare1 = con1.compare(12, 32);
        System.out.println("compare1 = " + compare1);


    }


    @Test//语法格式6：当lambda体只有一条语句时， return与大括号如有，都可以省略
    public void test6() {
        Comparator<Integer> con1 = (o1, o2) -> {
            return o1.compareTo(o2);
        };
        int compare1 = con1.compare(12, 32);
        System.out.println("compare1 = " + compare1);

        System.out.println("=======================================");
        Comparator<Integer> con2 = (o1, o2) -> o1.compareTo(o2);

        int compare2 = con1.compare(12, 32);
        System.out.println("compare2 = " + compare2);

    }


    @Test//语法格式4：lambda 若只需要一个参数时，参数的小括号可以省略
    public void test7() {


        Consumer<String> con2 = (o) ->
                System.out.println("o = " + o);
        con2.accept("大数据2");
    }

}
